
// <copyright file="BulkCopyDataReader.cs" company="Subhadra Software Solutions">
//   
// </copyright>
// <summary>
//   The bulk copy data reader.
// </summary>

namespace SubhadraSolutions.Sharp.Utils.Data
{
    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Data.Common;

    /// <summary>
    /// The bulk copy data reader.
    /// </summary>
    public sealed class BulkCopyDataReader : IDataReader
    {
        #region Fields

        /// <summary>
        /// The enumerator.
        /// </summary>
        private readonly IEnumerator<DbParameterCollection> enumerator;

        /// <summary>
        /// The indexes.
        /// </summary>
        private readonly Dictionary<string, int> indexes = new Dictionary<string, int>();

        #endregion Fields

        #region Constructors and Finalizers

        /// <summary>
        /// Initializes a new instance of the <see cref="BulkCopyDataReader"/> class.
        /// </summary>
        /// <param name="collection">
        /// The collection.
        /// </param>
        public BulkCopyDataReader(IList<DbParameterCollection> collection)
        {
            if (collection.Count > 0)
            {
                DbParameterCollection coll = collection[0];
                for (int i = 0; i < coll.Count; i++)
                {
                    this.indexes.Add(coll[i].ParameterName.ToUpper(), i);
                }

                this.FieldCount = coll.Count;
            }

            this.enumerator = collection.GetEnumerator();
        }

        #endregion Constructors and Finalizers

        #region Public Properties

        /// <summary>
        /// Gets the depth.
        /// </summary>
        public int Depth { get; private set; }

        /// <summary>
        /// Gets the field count.
        /// </summary>
        public int FieldCount { get; private set; }

        /// <summary>
        /// Gets a value indicating whether is closed.
        /// </summary>
        public bool IsClosed
        {
            get
            {
                return false;
            }
        }

        /// <summary>
        /// Gets the records affected.
        /// </summary>
        public int RecordsAffected { get; private set; }

        #endregion Public Properties

        #region Public Indexers

        /// <summary>
        /// The this.
        /// </summary>
        /// <param name="name">
        /// The name.
        /// </param>
        /// <returns>
        /// The <see cref="object"/>.
        /// </returns>
        public object this[string name]
        {
            get
            {
                int index = this.indexes[name.ToUpper()];
                DbParameter parameter = this.enumerator.Current[index];
                return parameter.Value;
            }
        }

        /// <summary>
        /// The this.
        /// </summary>
        /// <param name="i">
        /// The i.
        /// </param>
        /// <returns>
        /// The <see cref="object"/>.
        /// </returns>
        public object this[int i]
        {
            get
            {
                return this.enumerator.Current[i].Value;
            }
        }

        #endregion Public Indexers

        #region Public Methods and Operators

        /// <summary>
        /// The close.
        /// </summary>
        public void Close()
        {
        }

        /// <summary>
        /// The dispose.
        /// </summary>
        public void Dispose()
        {
        }

        /// <summary>
        /// The get boolean.
        /// </summary>
        /// <param name="i">
        /// The i.
        /// </param>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        public bool GetBoolean(int i)
        {
            return (bool)this.enumerator.Current[i].Value;
        }

        /// <summary>
        /// The get byte.
        /// </summary>
        /// <param name="i">
        /// The i.
        /// </param>
        /// <returns>
        /// The <see cref="byte"/>.
        /// </returns>
        public byte GetByte(int i)
        {
            return (byte)this.enumerator.Current[i].Value;
        }

        /// <summary>
        /// The get bytes.
        /// </summary>
        /// <param name="i">
        /// The i.
        /// </param>
        /// <param name="fieldOffset">
        /// The field offset.
        /// </param>
        /// <param name="buffer">
        /// The buffer.
        /// </param>
        /// <param name="bufferOffset">
        /// The bufferOffset.
        /// </param>
        /// <param name="length">
        /// The length.
        /// </param>
        /// <returns>
        /// The <see cref="long"/>.
        /// </returns>
        public long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferOffset, int length)
        {
            return 0;
        }

        /// <summary>
        /// The get char.
        /// </summary>
        /// <param name="i">
        /// The i.
        /// </param>
        /// <returns>
        /// The <see cref="char"/>.
        /// </returns>
        public char GetChar(int i)
        {
            return (char)this.enumerator.Current[i].Value;
        }

        /// <summary>
        /// The get chars.
        /// </summary>
        /// <param name="i">
        /// The i.
        /// </param>
        /// <param name="fieldOffset">
        /// The fieldOffset.
        /// </param>
        /// <param name="buffer">
        /// The buffer.
        /// </param>
        /// <param name="bufferOffset">
        /// The bufferOffset.
        /// </param>
        /// <param name="length">
        /// The length.
        /// </param>
        /// <returns>
        /// The <see cref="long"/>.
        /// </returns>
        public long GetChars(int i, long fieldOffset, char[] buffer, int bufferOffset, int length)
        {
            return 0;
        }

        /// <summary>
        /// The get data.
        /// </summary>
        /// <param name="i">
        /// The i.
        /// </param>
        /// <returns>
        /// The <see cref="IDataReader"/>.
        /// </returns>
        public IDataReader GetData(int i)
        {
            return this;
        }

        /// <summary>
        /// The get data type name.
        /// </summary>
        /// <param name="i">
        /// The i.
        /// </param>
        /// <returns>
        /// The <see cref="string"/>.
        /// </returns>
        public string GetDataTypeName(int i)
        {
            if (this.enumerator.Current[i].Value != null)
            {
                return this.enumerator.Current[i].Value.GetType().FullName;
            }

            return null;
        }

        /// <summary>
        /// The get date time.
        /// </summary>
        /// <param name="i">
        /// The i.
        /// </param>
        /// <returns>
        /// The <see cref="DateTime"/>.
        /// </returns>
        public DateTime GetDateTime(int i)
        {
            return (DateTime)this.enumerator.Current[i].Value;
        }

        /// <summary>
        /// The get decimal.
        /// </summary>
        /// <param name="i">
        /// The i.
        /// </param>
        /// <returns>
        /// The <see cref="decimal"/>.
        /// </returns>
        public decimal GetDecimal(int i)
        {
            return (decimal)this.enumerator.Current[i].Value;
        }

        /// <summary>
        /// The get double.
        /// </summary>
        /// <param name="i">
        /// The i.
        /// </param>
        /// <returns>
        /// The <see cref="double"/>.
        /// </returns>
        public double GetDouble(int i)
        {
            return (double)this.enumerator.Current[i].Value;
        }

        /// <summary>
        /// The get field type.
        /// </summary>
        /// <param name="i">
        /// The i.
        /// </param>
        /// <returns>
        /// The <see cref="Type"/>.
        /// </returns>
        public Type GetFieldType(int i)
        {
            if (this.enumerator.Current[i].Value != null)
            {
                return this.enumerator.Current[i].Value.GetType();
            }

            return null;
        }

        /// <summary>
        /// The get float.
        /// </summary>
        /// <param name="i">
        /// The i.
        /// </param>
        /// <returns>
        /// The <see cref="float"/>.
        /// </returns>
        public float GetFloat(int i)
        {
            return (float)this.enumerator.Current[i].Value;
        }

        /// <summary>
        /// The get guid.
        /// </summary>
        /// <param name="i">
        /// The i.
        /// </param>
        /// <returns>
        /// The <see cref="Guid"/>.
        /// </returns>
        public Guid GetGuid(int i)
        {
            return (Guid)this.enumerator.Current[i].Value;
        }

        /// <summary>
        /// The get int 16.
        /// </summary>
        /// <param name="i">
        /// The i.
        /// </param>
        /// <returns>
        /// The <see cref="short"/>.
        /// </returns>
        public short GetInt16(int i)
        {
            return (short)this.enumerator.Current[i].Value;
        }

        /// <summary>
        /// The get int 32.
        /// </summary>
        /// <param name="i">
        /// The i.
        /// </param>
        /// <returns>
        /// The <see cref="int"/>.
        /// </returns>
        public int GetInt32(int i)
        {
            return (int)this.enumerator.Current[i].Value;
        }

        /// <summary>
        /// The get int 64.
        /// </summary>
        /// <param name="i">
        /// The i.
        /// </param>
        /// <returns>
        /// The <see cref="long"/>.
        /// </returns>
        public long GetInt64(int i)
        {
            return (long)this.enumerator.Current[i].Value;
        }

        /// <summary>
        /// The get name.
        /// </summary>
        /// <param name="i">
        /// The i.
        /// </param>
        /// <returns>
        /// The <see cref="string"/>.
        /// </returns>
        public string GetName(int i)
        {
            return this.enumerator.Current[i].ParameterName;
        }

        /// <summary>
        /// The get ordinal.
        /// </summary>
        /// <param name="name">
        /// The name.
        /// </param>
        /// <returns>
        /// The <see cref="int"/>.
        /// </returns>
        public int GetOrdinal(string name)
        {
            return this.indexes[name.ToUpper()];
        }

        /// <summary>
        /// The get schema table.
        /// </summary>
        /// <returns>
        /// The <see cref="DataTable"/>.
        /// </returns>
        public DataTable GetSchemaTable()
        {
            return null;
        }

        /// <summary>
        /// The get string.
        /// </summary>
        /// <param name="i">
        /// The i.
        /// </param>
        /// <returns>
        /// The <see cref="string"/>.
        /// </returns>
        public string GetString(int i)
        {
            return (string)this.enumerator.Current[i].Value;
        }

        /// <summary>
        /// The get value.
        /// </summary>
        /// <param name="i">
        /// The i.
        /// </param>
        /// <returns>
        /// The <see cref="object"/>.
        /// </returns>
        public object GetValue(int i)
        {
            return this.enumerator.Current[i].Value;
        }

        /// <summary>
        /// The get values.
        /// </summary>
        /// <param name="values">
        /// The values.
        /// </param>
        /// <returns>
        /// The <see cref="int"/>.
        /// </returns>
        public int GetValues(object[] values)
        {
            return 0;
        }

        /// <summary>
        /// The is db null.
        /// </summary>
        /// <param name="i">
        /// The i.
        /// </param>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        public bool IsDBNull(int i)
        {
            return this.enumerator.Current[i].Value == null || this.enumerator.Current[i].Value == DBNull.Value;
        }

        /// <summary>
        /// The next result.
        /// </summary>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        public bool NextResult()
        {
            return true;
        }

        /// <summary>
        /// The read.
        /// </summary>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        public bool Read()
        {
            return this.enumerator.MoveNext();
        }

        #endregion Public Methods and Operators
    }
}